Skip to content

4.1. Linting

What does formatting protect?

Formatting removes review noise so behavioral changes stand out. Linting catches likely defects, insecure patterns, debug output, stale imports, and inconsistent APIs before tests run. Neither replaces tests or design review.

Which tools own which files?

Files Formatter/checker
Python Ruff format and import sorting; Ruff lint; ty types
Markdown/JSON/TOML/YAML/Dockerfile dprint
Shell shfmt and ShellCheck
GitHub Actions actionlint
Python metadata/lock validate-pyproject and uv lock --check

The root tasks delegate to the component task instead of duplicating flags.

How strict is Ruff?

The project selects broad correctness, security, modernization, performance, logging, and style rule families. Tests receive only justified exceptions such as assert and diagnostic print use. A production file should not accumulate file-wide suppressions.

[tool.ruff]
line-length = 120

[tool.ruff.format]
docstring-code-format = true
line-ending = "lf"
quote-style = "double"

The complete rule list lives in agents/python/pyproject.toml; prose should not duplicate it.

How do you format and check everything?

From the repository root:

mise run format
mise run check

format may modify files. Review the diff afterward. check runs docs rules/build, dprint, Python lint/types/audit, shell checks, and workflow lint without intentionally rewriting sources.

Why do docs have structural checks?

scripts/check-docs.sh verifies every course page has description front matter, an FAQ H2, question-form H2 headings, no machine-specific paths, and no retired registry reference. A site that renders can still have a broken teaching contract, so structure is checked before Zensical builds.

What is the lint checkpoint?

mise run format
git diff --check
mise run check

Continue only after reviewing formatter changes and resolving every warning at its cause. A warning-free gate is part of correctness, not optional polish.